------------------------------------------------------------------------
-- Multiplicador de punto flotante 
-- 
-- Descripcion: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--              xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--              xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--
-- Fecha: 18/06/2013
--
-- TODO: 
--    - Incluir control de overflow/underflow
--    - Incluir los dos casos de resultados (1x.xxxxxx y 01.xxxxxx)
--   
------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity mult_PF is
	generic(
		N	: natural:= 32;	-- tammano del numero empaquetado en bits
		exp : natural:= 8	-- tamano del exponente en bits
	);
	port(
		clk : in std_logic;
		a   : in std_logic_vector(N-1 downto 0);
		b   : in std_logic_vector(N-1 downto 0);
		z   : out std_logic_vector(N-1 downto 0));
end entity mult_PF;

architecture mult_PF_arq of mult_PF is
	constant ZERO_EXP : unsigned(exp-1 downto 0):=(others => '0');
	--constant ONES_EXP : std_logic_vector(exp-1 downto 0):=(others => '1');  
	signal zero_flag  : std_logic:= '0';
	--signal inf_flag   : std_logic:='0';
	signal exp_a      : unsigned(N-2 downto N-2-exp):= (others =>'0'); -- 30 downto 22
	signal mantissa_a : unsigned(N-3-exp downto 0):= (others =>'0');   -- 21 downto 0
	signal exp_b      : unsigned(N-2 downto N-2-exp):= (others =>'0'); -- 30 downto 22
	signal mantissa_b : unsigned(N-3-exp downto 0):= (others =>'0');   -- 21 downto 0
	signal exp_z      : unsigned(N-2 downto N-2-exp):= (others =>'0'); -- 30 downto 22
	signal mantissa_z : unsigned(N-3-exp downto 0):= (others =>'0');   -- 21 downto 0
	signal sign_z     : std_logic:= '0';
	signal aux_z      : unsigned(2*(N-2-exp)-1 downto 0);

begin

	sign_z <= a(N-1) xor b(N-1);

	exp_a <= unsigned(a(N-2 downto N-2-exp));
	mantissa_a <= unsigned(a(N-3-exp downto 0));

	exp_b <= unsigned(b(N-2 downto N-2-EXP));
	mantissa_b <= unsigned(b(N-3-exp downto 0));

	zero_flag<= '1' when exp_a=ZERO_EXP or exp_b=ZERO_EXP else '0';

	exp_z <= exp_a + exp_b when zero_flag='0' else (others => '0');
	aux_z <= mantissa_a*mantissa_b;

	mantissa_z <= aux_z(2*(N-3-exp)-1 downto (N-3-exp)-1);

	z <= sign_z & std_logic_vector(exp_z) & std_logic_vector(mantissa_z);

end architecture mult_PF_arq;
